package cn.jly.boot.mp.cron;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @PackageName cn.jly.boot.mp.cron
 * @ClassName SchedulerTask
 * @Description 测试spring自带的定时调度任务
 * @Author 姬岚洋
 * @Date 2021/1/5 下午 4:40
 */
@Component
public class SpringSchedulerTask {
    /**
     * 计数器
     */
    private static final AtomicLong COUNT = new AtomicLong(0L);

    private static final Logger LOGGER = LoggerFactory.getLogger(SpringSchedulerTask.class);

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss.SSS");

    /**
     * fixedRate 说明
     *
     * @Scheduled(fixedRate = 6000)：上一次开始执行时间点之后 6 秒再执行。
     * @Scheduled(fixedDelay = 6000)：上一次执行完毕时间点之后 6 秒再执行。
     * @Scheduled(initialDelay=1000, fixedRate=6000)：第一次延迟 1 秒后执行，之后按 fixedRate 的规则每 6 秒执行一次。
     * cron 说明
     * <p>
     * cron 一共有七位，最后一位是年，Spring Boot 定时方案中只需要设置六位即可：
     * <p>
     * 第一位，表示秒，取值 0 ~ 59；
     * 第二位，表示分，取值 0 ~ 59；
     * 第三位，表示小时，取值 0 ~ 23；
     * 第四位，日期天/日，取值 1 ~ 31；
     * 第五位，日期月份，取值 1~12；
     * 第六位，星期，取值 1 ~ 7，星期一，星期二...，注，不是第 1 周、第 2 周的意思，另外，1 表示星期天，2 表示星期一；
     * 第七位，年份，可以留空，取值 1970 ~ 2099。
     * cron 中，还有一些特殊的符号，含义如下：
     * <p>
     * （*）星号，可以理解为每的意思，每秒、每分、每天、每月、每年...。
     * （?）问号，问号只能出现在日期和星期这两个位置，表示这个位置的值不确定，每天 3 点执行，因此第六位星期的位置，是不需要关注的，就是不确定的值；同时，日期和星期是两个相互排斥的元素，通过问号来表明不指定值，比如 1 月 10 日是星期一，如果在星期的位置另指定星期二，就前后冲突矛盾了。
     * （-）减号，表达一个范围，如在小时字段中使用“10 ~ 12”，则表示从 10 到 12 点，即 10、11、12。
     * （,）逗号，表达一个列表值，如在星期字段中使用“1、2、4”，则表示星期一、星期二、星期四。
     * （/）斜杠，如 x/y，x 是开始值，y 是步长，比如在第一位（秒），0/15 就是从 0 秒开始，每隔 15 秒执行一次，最后就是 0、15、30、45、60，另
     * 每y，等同于 0/y。
     * 下面列举几个常用的例子。
     * <p>
     * 0 0 3 * * ? ：每天 3点执行；
     * 0 5 3 * * ?：每天 3点 5分执行；
     * 0 5 3 ? * *：每天 3点 5分执行，与上面作用相同；
     * 0 5/10 3 * * ?：每天 3点的 5分、15分、25分、35分、45分、55分这几个时间点执行；
     * 0 10 3 ? * 1：每周星期天，3点 10分执行，注，1表示星期天；
     * 0 10 3 ? * 1#3：每个月的第三个星期，星期天执行，#号只能出现在星期的位置。
     */
    @Scheduled(cron = "*/6 * * * * ?")
    public void process() {
        LOGGER.info("spring默认调度方法执行次数 {}, 当前时间 {}", COUNT.getAndIncrement(), DATE_TIME_FORMATTER.format(LocalDateTime.now()));
    }
}
